package com.example.myjavafx.controller;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelReader;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.util.Base64;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javafx.embed.swing.SwingFXUtils;
import javafx.stage.FileChooser;

/**
 * @author admin
 */
public class ImageViewController {
    @FXML
    public Label coordinatesLabel;
    @FXML private ImageView imageView;
    @FXML private Canvas selectionCanvas;
    @FXML private Label statusLabel;

    private double startX, startY, endX, endY;
    private Image originalImage;
    private Image image;

    private double rectX, rectY, rectWidth, rectHeight;
    /**
     * 初始化 Canvas 与 ImageView 同步尺寸
     */

    @FXML
    public void initialize() {
        imageView.fitWidthProperty().addListener((obs, oldVal, newVal) -> {
            selectionCanvas.setWidth(newVal.doubleValue());
        });
        imageView.fitHeightProperty().addListener((obs, oldVal, newVal) -> {
            selectionCanvas.setHeight(newVal.doubleValue());
        });
    }

    /**
     * 点击按钮加载图片
     */
    @FXML
    private void loadImage() {
        statusLabel.setText("加载中...");
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("http://localhost:8080/get_image"))
                .build();

        client.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray())
                .thenApply(HttpResponse::body)
                .thenApply(bytes -> new Image(new ByteArrayInputStream(bytes)))
                .thenAccept(image -> {
                    Platform.runLater(() -> {
                        originalImage = image;
                        imageView.setImage(image);
                        clearSelection();
                        statusLabel.setText("图片加载成功");
                    });
                })
                .exceptionally(e -> {
                    Platform.runLater(() ->
                            statusLabel.setText("加载失败: " + e.getMessage()));
                    return null;
                });
    }

    /**
     * 处理鼠标事件：记录坐标并绘制选区
     * @param event --
     */
    @FXML
    private void onMousePressed(MouseEvent event) {
        startX = event.getX();
        startY = event.getY();
        clearSelection();
    }

    @FXML
    private void onMouseDragged(MouseEvent event) {
        endX = event.getX();
        endY = event.getY();
        drawSelectionRect();
    }

    @FXML
    private void onMouseReleased(MouseEvent event) {
        endX = event.getX();
        endY = event.getY();
        drawSelectionRect();
    }

    /**
     * 绘制选区矩形
     */
    private void drawSelectionRect() {
        GraphicsContext gc = selectionCanvas.getGraphicsContext2D();
        gc.clearRect(0, 0, selectionCanvas.getWidth(), selectionCanvas.getHeight());
        gc.setStroke(Color.RED);
        gc.setLineWidth(2);
        gc.strokeRect(
                Math.min(startX, endX),
                Math.min(startY, endY),
                Math.abs(endX - startX),
                Math.abs(endY - startY)
        );
    }

    /**
     * 清除选区
     */
    private void clearSelection() {
        GraphicsContext gc = selectionCanvas.getGraphicsContext2D();
        gc.clearRect(0, 0, selectionCanvas.getWidth(), selectionCanvas.getHeight());
    }

    /**
     * 提交剪切请求
     */
    @FXML
    private void submitCrop() {
        if (originalImage == null) {
            statusLabel.setText("请先加载图片");
            return;
        }

        // 转换屏幕坐标到图片实际坐标
        double scaleX = originalImage.getWidth() / imageView.getBoundsInParent().getWidth();
        double scaleY = originalImage.getHeight() / imageView.getBoundsInParent().getHeight();

        int cropX = (int) (Math.min(startX, endX) * scaleX);
        int cropY = (int) (Math.min(startY, endY) * scaleY);
        int cropWidth = (int) (Math.abs(endX - startX) * scaleX);
        int cropHeight = (int) (Math.abs(endY - startY) * scaleY);

        // 剪切图片
        WritableImage croppedImage = new WritableImage(cropWidth, cropHeight);
        PixelReader reader = originalImage.getPixelReader();
        croppedImage.getPixelWriter().setPixels(
                0, 0, cropWidth, cropHeight, reader, cropX, cropY
        );

        // 将图像转为 Base64
        try {
            BufferedImage bufferedImage = SwingFXUtils.fromFXImage(croppedImage, null);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "png", baos);
            String base64Image = Base64.getEncoder().encodeToString(baos.toByteArray());

            // 构建 JSON 请求体
            String jsonBody = String.format(
                    "{\"x\": %d, \"y\": %d, \"width\": %d, \"height\": %d, \"image\": \"%s\"}",
                    cropX, cropY, cropWidth, cropHeight, base64Image
            );

            // 发送 POST 请求
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create("http://localhost:8080/process_crop"))
                    .header("Content-Type", "application/json")
                    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                    .build();

            client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                    .thenAccept(response -> {
                        Platform.runLater(() -> {
                            statusLabel.setText("提交结果: " + response.body());
                        });
                    })
                    .exceptionally(e -> {
                        Platform.runLater(() ->
                                statusLabel.setText("提交失败: " + e.getMessage()));
                        return null;
                    });

        } catch (IOException e) {
            statusLabel.setText("图像转换错误: " + e.getMessage());
        }
    }

    public void uploadImage(ActionEvent actionEvent) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("Image Files", "*.png", "*.jpg", "*.jpeg", "*.gif")
        );
        File file = fileChooser.showOpenDialog(imageView.getScene().getWindow());
        if (file != null) {
            image = new Image(file.toURI().toString());
            imageView.setImage(image);
            clearSelection();
        }
    }
}
